# src/data_collector/platforms/youtube_collector.py

import os
import logging
import time
from datetime import datetime
from itertools import cycle

from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from googleapiclient.http import set_user_agent
import httplib2

from sqlalchemy.orm import Session

from models.comment_schema import RawComment, VideoSource
from src.utils.youtube_client import get_youtube_service
# src/data_collector/platforms/youtube_collector.py

from data_collector.interfaces.comment_collector_interface import CommentCollector

logger = logging.getLogger(__name__)


class YouTubeCommentCollector(CommentCollector):
    def __init__(self, api_keys=None):
        """
        初始化 YouTube 评论采集器
        :param api_keys: API 密钥列表（用于轮换）
        """
        super().__init__(api_keys)
        self.api_key_pool = cycle(api_keys) if api_keys else None
        self.current_api_key = next(self.api_key_pool) if self.api_key_pool else os.getenv("YT_API_KEY")
        self.youtube = self._create_youtube_client()

    def _create_youtube_client(self):
        """
        创建带超时限制的 YouTube 客户端
        """
        try:
            # 使用全局 Key 轮换器（来自 youtube_client 模块）
            from src.utils.youtube_client import get_youtube_service
            youtube = get_youtube_service()
            return youtube
        except Exception as e:
            logger.error(f"❌ 创建 YouTube 客户端失败: {str(e)}")
            raise

    def get_comments(self, video_info, max_comments_per_video=500):
        """
        获取单个视频的主评论（支持分页、自动重试）
        :param video_info: 包含 id 和 video_id 的字典
        :param max_comments_per_video: 最大评论数
        :return: RawComment 列表
        """
        video_id = video_info["video_id"]
        comments = []
        next_page_token = None
        retry_count = 0
        max_retries = 5

        while len(comments) < max_comments_per_video:
            remaining = max_comments_per_video - len(comments)
            fetch_count = min(100, remaining)

            params = {
                "part": "snippet,replies",
                "videoId": video_id,
                "maxResults": fetch_count,
                "pageToken": next_page_token,
                "order": "relevance"
            }

            while retry_count < max_retries:
                try:
                    response = self.youtube.commentThreads().list(**params).execute()
                    break
                except (HttpError, ConnectionError, TimeoutError) as e:
                    retry_count += 1
                    wait_time = min(5 * retry_count, 30)
                    logger.warning(f"⚠️ 连接失败，第 {retry_count} 次重试 ({wait_time}s): {str(e)}")
                    time.sleep(wait_time)
            else:
                logger.error(f"❌ 获取视频 {video_id} 评论失败: 达到最大重试次数")
                continue

            items = response.get("items", [])
            if not items:
                logger.info(f"🔚 视频 {video_id} 已无更多评论")
                break

            for item in items:
                snippet = item["snippet"]["topLevelComment"]["snippet"]

                main_comment = RawComment(
                    author=snippet["authorDisplayName"],
                    video_id=video_id,
                    # video_source_id=video_info["id"],  # 设置 video_source_id
                    comment_text=snippet["textOriginal"],
                    published_at=datetime.strptime(snippet["publishedAt"], "%Y-%m-%dT%H:%M:%SZ"),
                    like_count=snippet.get("likeCount", 0),
                    parent_id=None,  # 主评论没有父评论
                    parent_text=None,
                    top_comment_id=item["snippet"]["topLevelComment"]["id"],
                    is_analyzed=False,
                    platform="youtube",
                    source_type="video",
                    user_id=snippet.get("authorChannelId", {}).get("value")  # 可选：用户ID
                )

                comments.append(main_comment)

            next_page_token = response.get("nextPageToken")
            if not next_page_token:
                break

            time.sleep(2)  # 控制请求频率，避免触发配额限制

        logger.info(f"✅ 已抓取 {len(comments)} 条主评论 from 视频 {video_id}")
        return comments

    def get_replies(self, session: Session, video_info: dict):
        """
        获取指定视频的所有子评论（回复）
        :param session: 数据库会话
        :param video_info: 包含 id 和 video_id 的字典，如 {"id": 123, "video_id": "abcxyz"}
        """
        logger.info(f"🔁 开始采集视频 {video_info['video_id']} 的子评论...")

        next_page_token = None
        total_replies = 0
        retry_count = 0
        max_retries = 5

        while retry_count < max_retries:
            try:
                response = self.youtube.commentThreads().list(
                    part="snippet,replies",
                    videoId=video_info["video_id"],
                    pageToken=next_page_token,
                    maxResults=100,
                    textFormat="plainText"
                ).execute()
            except HttpError as e:
                logger.error(f"❌ 获取子评论失败: {str(e)}")
                retry_count += 1
                logger.info(f"🔄 第 {retry_count} 次重试...")
                time.sleep(5)
                continue

            items = response.get("items", [])

            for item in items:
                replies = item.get("replies", {}).get("comments", [])
                top_level_id = item["snippet"]["topLevelComment"]["id"]

                for reply in replies:
                    reply_snippet = reply["snippet"]

                    existing = session.query(RawComment).filter_by(top_comment_id=reply["id"]).first()
                    if existing:
                        continue

                    parent_text = item["snippet"]["topLevelComment"]["snippet"]["textOriginal"]

                    reply_obj = RawComment(
                        author=reply_snippet["authorDisplayName"],
                        video_id=video_info["video_id"],
                        comment_text=reply_snippet["textOriginal"],
                        published_at=datetime.strptime(reply_snippet["publishedAt"], "%Y-%m-%dT%H:%M:%SZ"),
                        like_count=reply_snippet.get("likeCount", 0),
                        parent_id=top_level_id,
                        parent_text=parent_text,
                        top_comment_id=reply["id"],
                        is_analyzed=False,
                        video_source_id=video_info["id"],  # ✅ 现在可以安全访问
                        platform="youtube",
                        source_type="video"
                    )

                    session.add(reply_obj)
                    total_replies += 1

            next_page_token = response.get("nextPageToken")
            if not next_page_token:
                break

            time.sleep(2)

        session.commit()
        logger.info(f"✅ 成功采集 {total_replies} 条子评论 from 视频 {video_info['video_id']}")